package com.vlyman.aop;

import com.vlyman.annotation.OptimisticLockRetry;
import com.vlyman.exception.RetryException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 类描述：
 *  乐观锁失败后重试切面
 * @author chenjs
 * @date 2020/4/21 15:33
 **/
@Aspect
@Slf4j
@Component
@Order(4)
public class OptimisticLockRetryAspect {

    @Pointcut("@annotation(com.vlyman.annotation.OptimisticLockRetry)")
    public void retryPointcut(){}

    @Around("retryPointcut() && @annotation(retry)")
    public Object doAround(ProceedingJoinPoint joinPoint, OptimisticLockRetry retry) throws Throwable {
        int count = 0;
        do {
            count++;
            try {
                return joinPoint.proceed();
            } catch (RetryException e) {
                log.warn("乐观锁更新失败！重试次数：" + count);
                if (count > retry.retryTime()) {
                    log.error("乐观锁失败后重试超过阈值！", e);
                    throw e;
                }
            }
        } while (true);
    }
}
